/*
 * FSWUniCEUB - 2008
 * 
 * Este arquivo é de propriedade da Fábrica de Software do UniCEUB
 * 
 * Para mais informações entre em contato com a coordenação do
 * curso de Ciência da Computação da instituição.
 */

package br.uniceub.fsw.util;

import br.uniceub.fsw.seguranca.vo.ModuloVO;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 * Responsável por montar componentes pré-definidos usados
 * intensamente no desenvolvimento da aplicação.
 * 
 * @author Bruno
 */
public class MontadorHtml {
    /**
     * Monta uma grid a partir de um objeto tabela
     * previamente montado.
     * 
     * @param tabela Objeto tabela com as informações da grid.
     * @return String html montando a grid da tela.
     */
    public String montarTabelaConsulta(TabelaHtml tabela) {
        if(tabela == null || !tabela.validarCampos()) {
            return "";
        }
        
        StringBuffer html = new StringBuffer();
        
        html.append("<script language=\"Javascript\">");
        html.append("function selecionar(id) { ");
        html.append(" window.opener.document.formulario.operacao.value = \"consultar\"; ");
        html.append(" window.opener.document.formulario." + tabela.getCampoRetorno() + ".value = id; ");
        html.append(" window.opener.document.formulario.submit(); ");
        html.append(" window.close(); ");
        html.append(" }");
        html.append("</script>");
        html.append("<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\">");
        html.append("<tr class=\"sgirccolunacabecalhotabela\">");
        
        for(int i = 0; i < tabela.buscarQuantidadeCampos(); i++) {
            if(tabela.buscarStatus(i)) {
                html.append("<td width=\"" + tabela.buscarTamanho(i).toString() + "%\">" + tabela.buscarTitulo(i) + "</td>");
            }
        }

        html.append("<td width=\"20%\">Op&ccedil;&atilde;o</td>");

        html.append("</tr>");

        for(int i = 0; i < tabela.buscarQuantidadeLinhas(); i++) {
            html.append("<tr class=\"sgirccolunalinhatabela\">");
            for(int j = 0; j < tabela.buscarQuantidadeCampos(); j++) {
                if(tabela.buscarStatus(j)) {
                    html.append("<td>" + tabela.buscarRegistro(i).get(j) + "</td>");
                }
            }
            html.append("<td><a href=\"javascript: selecionar(" + tabela.buscarRegistro(i).get(0) + ");\">Selecionar</a></td>");
            html.append("</tr>");
        }

        html.append("</table>");
        
        return html.toString();
    }
    
    /**
     * Monta uma grid a partir de um objeto tabela
     * previamente montado.
     * 
     * @param tabela Objeto tabela com as informações da grid.
     * @return String html montando a grid da tela.
     */
    public String montarTabelaManutencao(TabelaHtml tabela) {
        if(tabela == null || !tabela.validarCampos()) {
            return "";
        }
        
        StringBuffer html = new StringBuffer();
        
        html.append("<script language=\"Javascript\">");
        html.append("function excluirItem(id) { ");
        html.append(" window.document.formulario.operacao.value = \"excluirItem\"; ");
        html.append(" window.document.formulario." + tabela.getCampoRetorno() + ".value = id; ");
        html.append(" window.document.formulario.submit(); ");
        html.append(" }");
        html.append("</script>");
        html.append("<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\">");
        html.append("<tr class=\"sgirccolunacabecalhotabela\">");
        
        for(int i = 0; i < tabela.buscarQuantidadeCampos(); i++) {
            if(tabela.buscarStatus(i)) {
                html.append("<td width=\"" + tabela.buscarTamanho(i).toString() + "%\">" + tabela.buscarTitulo(i) + "</td>");
            }
        }

        html.append("<td width=\"20%\">Op&ccedil;&atilde;o</td>");

        html.append("</tr>");

        for(int i = 0; i < tabela.buscarQuantidadeLinhas(); i++) {
            html.append("<tr class=\"sgirccolunalinhatabela\">");
            for(int j = 0; j < tabela.buscarQuantidadeCampos(); j++) {
                if(tabela.buscarStatus(j)) {
                    html.append("<td>" + tabela.buscarRegistro(i).get(j) + "</td>");
                }
            }
            html.append("<td><a href=\"javascript: excluirItem(" + tabela.buscarRegistro(i).get(0) + ");\">Excluir</a></td>");
            html.append("</tr>");
        }

        html.append("</table>");
        
        return html.toString();
    }
    
    /**
     * Monta uma grid a partir de um objeto tabela
     * previamente montado.
     * 
     * @param tabela Objeto tabela com as informações da grid.
     * @return String html montando a grid da tela.
     */
    public String montarTabelaDetalhar(TabelaHtml tabela, String action) {
        if(tabela == null || !tabela.validarCampos()) {
            return "";
        }
        
        StringBuffer html = new StringBuffer();
        
        html.append("<script language=\"Javascript\">");
        html.append("function detalhar(id) { ");
        html.append(" window.document.formulario.operacao.value = \"detalhar\"; ");
        html.append(" window.document.formulario." + tabela.getCampoRetorno() + ".value = id; ");
        html.append(" window.document.formulario.action = \"" + action + "\"; ");
        html.append(" window.document.formulario.submit(); ");
        html.append(" }");
        html.append("</script>");
        html.append("<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\">");
        html.append("<tr class=\"sgirccolunacabecalhotabela\">");
        
        for(int i = 0; i < tabela.buscarQuantidadeCampos(); i++) {
            if(tabela.buscarStatus(i)) {
                html.append("<td width=\"" + tabela.buscarTamanho(i).toString() + "%\">" + tabela.buscarTitulo(i) + "</td>");
            }
        }

        html.append("<td width=\"20%\">Op&ccedil;&atilde;o</td>");

        html.append("</tr>");

        for(int i = 0; i < tabela.buscarQuantidadeLinhas(); i++) {
            html.append("<tr class=\"sgirccolunalinhatabela\">");
            for(int j = 0; j < tabela.buscarQuantidadeCampos(); j++) {
                if(tabela.buscarStatus(j)) {
                    html.append("<td>" + tabela.buscarRegistro(i).get(j) + "</td>");
                }
            }
            html.append("<td><a href=\"javascript: detalhar(" + tabela.buscarRegistro(i).get(0) + ");\">Detalhar</a></td>");
            html.append("</tr>");
        }

        html.append("</table>");
        
        return html.toString();
    }
    
    /**
     * Monta uma combo a partir de uma lista de strings
     * A lista deve conter:
     * - na posição [0], o valor do identificador do item
     * - na posição [1], o valor do texto que aparecerá na combo
     * 
     * @param nome Nome do campo.
     * @param listaValores Lista de valores string para cada item do combo.
     * @param idSelecionado Id do item que deve aparecer selecionado.
     * @param habilitado Indica se a combo está habilitada ou não.
     * @return String HTML da combo.
     */
    public String montarCampoCombo(String nome, List<List> listaValores, Integer idSelecionado, boolean habilitado) {
        StringBuffer html = new StringBuffer();
        
        html.append("<select name=\"");
        html.append(nome);
        html.append("\" ");
        if(!habilitado) {
            html.append("disabled ");
        }
        html.append("class=\"dropdownlist\" onfocus=\"this.className='dropdownlistfocus';\" onblur=\"this.className='dropdownlistblur';\" ");
        
        html.append(">");
        html.append("<option value=\"\"></option>");
        
        if(listaValores != null) {
            for(List<String> lista : listaValores) {
                html.append("<option value=\"");
                html.append(lista.get(0));
                html.append("\"");
                if(idSelecionado != null && lista.get(0).equals(idSelecionado.toString())) {
                    html.append(" selected");
                }
                html.append(">");
                html.append(lista.get(1));
                html.append("</option>");
            }
        }
        
        html.append("</select>");
        
        return html.toString();
    }
    
    /**
     * Monta uma combo a partir de uma lista de strings
     * A lista deve conter:
     * - na posição [0], o valor do identificador do item
     * - na posição [1], o valor do texto que aparecerá na combo
     * 
     * @param nome Nome do campo.
     * @param listaValores Lista de valores string para cada item do combo.
     * @param idSelecionado Id do item que deve aparecer selecionado.
     * @param habilitado Indica se a combo está habilitada ou não.
     * @param outros String com outros comandos.
     * @return String HTML da combo.
     */
    public String montarCampoComboEx(String nome, List<List> listaValores, Integer idSelecionado, boolean habilitado, String outros) {
        StringBuffer html = new StringBuffer();
        
        html.append("<select name=\"");
        html.append(nome);
        html.append("\" ");
        if(!habilitado) {
            html.append("disabled ");
        }
        html.append("class=\"dropdownlist\" onfocus=\"this.className='dropdownlistfocus';\" onblur=\"this.className='dropdownlistblur';\" ");
        if(outros != null && outros.trim().length() > 0) {
            html.append(outros);
        }
        html.append(">");
        html.append("<option value=\"\"></option>");
        
        if(listaValores != null) {
            for(List<String> lista : listaValores) {
                html.append("<option value=\"");
                html.append(lista.get(0));
                html.append("\"");
                if(idSelecionado != null && lista.get(0).equals(idSelecionado.toString())) {
                    html.append(" selected");
                }
                html.append(">");
                html.append(lista.get(1));
                html.append("</option>");
            }
        }
        
        html.append("</select>");
        
        return html.toString();
    }
    
    /**
     * Monta um item de uma caixa de combo.
     * 
     * @param registro
     * @param idSelecionado
     * @return String html do item da combo.
     */
    public String montarOptionCombo(List<String> registro, Integer idSelecionado, Integer nivel) {
        StringBuffer html = new StringBuffer();

        String espacos = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
        
        html.append("<option value=\"");
        html.append(registro.get(0));
        html.append("\"");
        if(idSelecionado != null && registro.get(0).equals(idSelecionado.toString())) {
            html.append(" selected");
        }
        html.append(">");
        for(int i = 0; i < nivel; i++) {
            html.append(espacos);
        }
        html.append(registro.get(1));
        html.append("</option>");
        
        return html.toString();
    }
    
    /**
     * Monta uma combo hierarquica a partir de uma lista de strings
     * A lista deve conter:
     * - na posição [0], o valor do identificador do item
     * - na posição [1], o valor do texto que aparecerá na combo
     * 
     * @param nome Nome do campo.
     * @param listaValores Lista de valores string para cada item do combo.
     * @param idSelecionado Id do item que deve aparecer selecionado.
     * @return String HTML da combo.
     */
    public String montarCampoComboHierarquico(String nome, List<List> listaValores, Integer idSelecionado, Integer idRaiz) {
        StringBuffer html = new StringBuffer();
        
        List<String> registroRaiz = new ArrayList<String>();
        
        for(int i = 0; i < listaValores.size(); i++) {
            if(idRaiz == listaValores.get(i).get(2)) {
                registroRaiz = listaValores.get(i);
                break;
            }
        }
        
        html.append("<select name=\"");
        html.append(nome);
        html.append("\" class=\"dropdownlist\" onfocus=\"this.className='dropdownlistfocus';\" onblur=\"this.className='dropdownlistblur';\">");
        html.append("<option value=\"\"></option>");
        
        int nivel = 0;

        html.append(montarOptionCombo(registroRaiz, idSelecionado, nivel));
        nivel++;
        
        int index = 0;

        Stack<List> stackModuloAtual = new Stack<List>();
        Stack<Integer> stackIndices = new Stack<Integer>();
        
        List<String> moduloAtual = registroRaiz;
        
        while(moduloAtual != null) {
            // Pega todos os filhos do módulo atual
            List<List> filhosModuloAtual = new ArrayList<List>();
            
            for(int i = 0; i < listaValores.size(); i++) {
                if(listaValores.get(i).get(2) != null && moduloAtual.get(0).equals(listaValores.get(i).get(2))) {
                    filhosModuloAtual.add(listaValores.get(i));
                }
            }
  
            List<List> filhosItem = new ArrayList<List>();
            
            if(filhosModuloAtual.size() == 0 || index >= filhosModuloAtual.size()) {
                break;
            } else {
                for(int i = 0; i < listaValores.size(); i++) {
                    if(listaValores.get(i).get(2) != null && filhosModuloAtual.get(index).get(0).equals(listaValores.get(i).get(2))) {
                        filhosItem.add(listaValores.get(i));
                    }
                }
                
                if(filhosItem.size() == 0) {
                    html.append(montarOptionCombo(filhosModuloAtual.get(index), idSelecionado, nivel));
                    index++;
                    if(!stackIndices.empty() && index >= filhosModuloAtual.size()) {
                        index = stackIndices.pop() + 1;
                        moduloAtual = stackModuloAtual.pop();
                        nivel--;
                    }
                } else {
                    stackIndices.push(index);
                    stackModuloAtual.push(moduloAtual);
                    moduloAtual = filhosModuloAtual.get(index);
                    index = 0;
                    html.append(montarOptionCombo(moduloAtual, idSelecionado, nivel));
                    nivel++;
                }
            }
        }

        html.append("</select>");
        
        return html.toString();
    }
    
    /**
     * Monta um campo escondido.
     * 
     * @param nome Nome do campo.
     * @param valor Valor do campo.
     * @return String HTML com o campo escondido.
     */
    public String montarCampoEscondido(String nome, String valor) {
        StringBuffer html = new StringBuffer();
        
        html.append("<input type=\"hidden\" name=\"");
        html.append(nome);
        html.append("\" value=\"");
        html.append(valor==null?new String(""):valor);
        html.append("\" />");
        
        return html.toString();
    }
    
    /**
     * Monta o checkbox com o valor selecionado ou não.
     * 
     * @param nome Nome do campo.
     * @param valor Valor do campo.
     * @return String HTML do checkbox.
     */
    public String montarCheckbox(String nome, Boolean valor) {
        StringBuffer html = new StringBuffer();
        
        html.append("<input name=\"");
        html.append(nome);
        html.append("\" type=\"checkbox\" class=\"checkbox\"");
        
        if(valor) {
            html.append(" checked");
        }
        
        html.append(">");
        
        return html.toString();
    }
    
    /**
     * Monta um campo texto de formulário.
     * 
     * @param nome Nome do campo.
     * @param tamanho Tamanho da caixa na tela.
     * @param maximoTamanho Tamanho máximo do valor inserido no campo.
     * @param valor Valor do campo.
     * @param outros Outros comandos necessários para o campo.
     * @return String HTML do campo texto.
     */
    public String montarCampoTexto(String nome, Integer tamanho, Integer maximoTamanho, String valor, String outros) {
        StringBuffer html = new StringBuffer();
        
        html.append("<input name=\"");
        html.append(nome);
        html.append("\" value=\"");
        html.append(valor==null?new String(""):valor);
        html.append("\" type=\"text\" ");
        html.append(tamanho==null?new String(""):new String("size=\"") + tamanho.toString() + new String("\" "));
        html.append(maximoTamanho==null?new String(""):new String("maxlength=\"") + maximoTamanho.toString() + new String("\" "));
        html.append(" class=\"textbox\" onfocus=\"this.className='textboxfocus';\" onblur=\"this.className='textboxblur';\"");
        html.append(outros==null?new String(""):new String(" ") + outros);
        html.append(">");
        
        return html.toString();
    }
    
    /**
     * Monta um campo texto de formulário.
     * 
     * @param nome Nome do campo.
     * @param tamanho Tamanho da caixa na tela.
     * @param maximoTamanho Tamanho máximo do valor inserido no campo.
     * @param valor Valor do campo.
     * @param outros Outros comandos necessários para o campo.
     * @return String HTML do campo texto.
     */
    public String montarCampoAreaTexto(String nome, Integer tamanho, Integer altura, String valor, String outros) {
        StringBuffer html = new StringBuffer();
        
        html.append("<textarea name=\"");
        html.append(nome);
        html.append("\" ");
        html.append(tamanho==null?new String(""):new String("cols=\"") + tamanho.toString() + new String("\" "));
        html.append(altura==null?new String(""):new String("rows=\"") + altura.toString() + new String("\" "));
        html.append(" class=\"textarea\" onfocus=\"this.className='textareafocus';\" onblur=\"this.className='textareablur';\"");
        html.append(outros==null?new String(""):new String(" ") + outros);
        html.append(">\n");
        if(valor != null)
             html.append(valor.replace("<", "&lt;").replace(">", "&gt;"));
        html.append("</textarea>");
        
        return html.toString();
    }
    
    /**
     * Monta um campo senha de formulário.
     * 
     * @param nome Nome do campo.
     * @param tamanho Tamanho da caixa na tela.
     * @param maximoTamanho Tamanho máximo do valor inserido no campo.
     * @param valor Valor do campo.
     * @param outros Outros comandos necessários para o campo.
     * @return String HTML do campo texto.
     */
    public String montarCampoSenha(String nome, Integer tamanho, Integer maximoTamanho, String valor, String outros) {
        StringBuffer html = new StringBuffer();
        
        html.append("<input name=\"");
        html.append(nome);
        html.append("\" value=\"");
        html.append(valor==null?new String(""):valor);
        html.append("\" type=\"password\" ");
        html.append(tamanho==null?new String(""):new String("size=\"") + tamanho.toString() + new String("\" "));
        html.append(maximoTamanho==null?new String(""):new String("maxlength=\"") + maximoTamanho.toString() + new String("\" "));
        html.append(" class=\"textbox\" onfocus=\"this.className='textboxfocus';\" onblur=\"this.className='textboxblur';\"");
        html.append(outros==null?new String(""):new String(" ") + outros);
        html.append(">");
        
        return html.toString();
    }
    
    /**
     * Monta o menu de funcionalidades de um módulo
     * 
     * @param listaModulo Lista dos módulos filhos do módulo principal.
     * @return String HTML do menu.
     */
    public String montarMenuPrincipal(List<ModuloVO> listaModulo) {
        StringBuffer sb = new StringBuffer();

        if(listaModulo == null || listaModulo.size() == 0) {
            sb.append("                                                        <tr>\n");
            sb.append("                                                            <td width=\"100%\">\n");
            sb.append("                                                                Usu&aacute;rio sem acesso aos m&oacute;dulos do sistema.\n");
            sb.append("                                                            </td>\n");
            sb.append("                                                        </tr>\n");
            
            return sb.toString();
        }
        
        for (int i = 0; i < listaModulo.size(); i++) {
            ModuloVO modulo = (ModuloVO) listaModulo.get(i);

            sb.append("                                                        <tr>\n");
            sb.append("                                                            <td width=\"100%\">\n");
            sb.append("                                                                <a href=\"" + modulo.getDsChamada() + "\">" + modulo.getDsModulo() + "</a>\n");
            sb.append("                                                            </td>\n");
            sb.append("                                                        </tr>\n");
            sb.append("                                                        <tr>\n");
            sb.append("                                                            <td colspan=\"6\">\n");
            sb.append("                                                                &nbsp;\n");
            sb.append("                                                            </td>\n");
            sb.append("                                                        </tr>\n");
        }
        
        return sb.toString();
    }
    
    /**
     * Monta menu de funcionalidades de um módulo.
     * 
     * @param listaModulo Lista dos módulos (caso de uso) que compõem o menu do módulo pai
     * @param mensagem Mensagem de retorno para a tela aonde o menu deveria aparecer.
     * @return String HTML do menu.
     */
    public String montarMenuFuncionalidades(List<ModuloVO> listaModulo, String mensagem) {
        StringBuilder sb = new StringBuilder();
        
        if(listaModulo.size() == 0) {
            mensagem = "Usu&aacute;rio sem acesso aos casos de uso deste m&oacute;dulo.";
            return null;
        }
        
        for (int i = 0; i < listaModulo.size(); i++) {
            ModuloVO modulo = (ModuloVO) listaModulo.get(i);

            sb.append("                                                <tr>\n");
            sb.append("                                                    <td class=\"menu_button\" width=\"100%\">\n");
            sb.append("                                                        <a href=\"" + modulo.getDsChamada() + "\">" + modulo.getDsModulo() + "</a>\n");
            sb.append("                                                    </td>\n");
            sb.append("                                                </tr>\n");
        }
        
        return sb.toString();
    }
    
    /**
     * Retorna o código HTML para mostrar os botões de confirmação da tela de consulta.
     * 
     * @return Html com os botões necessários na tela.
     */
    public String montarBotoesConfirmar() {
        StringBuffer html = new StringBuffer();
        
        html.append("<input type=\"button\" class=\"button\" value=\"Excluir\" onclick=\"excluir();\">\n");
        html.append("&nbsp;\n");
        html.append("<input type=\"button\" class=\"button\" value=\"Cancelar\" onclick=\"cancelar();\">\n");
        html.append("&nbsp;\n");
        
        return html.toString();
    }
    
    /**
     * Retorna o código HTML para mostrar os botões da tela CRUD.
     * 
     * @param modulo Objeto modulo.
     * @return Html com os botões necessários na tela.
     */
    public String montarBotoesTelaManter(Object objeto) {
        StringBuffer html = new StringBuffer();
        
        if(objeto == null) {
            html.append("<input type=\"button\" class=\"button\" value=\"Consultar\" onclick=\"consultar();\">\n");
            html.append("&nbsp;\n");
            html.append("<input type=\"button\" class=\"button\" value=\"Incluir\" onclick=\"incluir();\">\n");
            html.append("&nbsp;\n");
        } else {
            html.append("<input type=\"button\" class=\"button\" value=\"Alterar\" onclick=\"alterar();\">\n");
            html.append("&nbsp;\n");
            html.append("<input type=\"button\" class=\"button\" value=\"Excluir\" onclick=\"excluir();\">\n");
            html.append("&nbsp;\n");
        }
        html.append("<input type=\"button\" class=\"button\" value=\"Limpar\" onclick=\"limpar();\">\n");
        html.append("&nbsp;\n");
        html.append("<input type=\"button\" class=\"button\" value=\"Voltar\" onclick=\"voltar();\">\n");
        html.append("&nbsp;\n");
        
        return html.toString();
    }
    
    /**
     * Monta um campo do tipo arquivo.
     * 
     * @param noCampo Nome do campo.
     * @param tamanho Tamanho do campo.
     * @return código html do campo arquivo.
     */
    public String montarCampoArquivo(String noCampo, String tamanho) {
        StringBuffer html = new StringBuffer();
        
        html.append("<input type=\"file\" name=\"" + noCampo + "\" size=\"" + tamanho + "\">");
        
        return html.toString();
    }

    /**
     * Monta um link.
     * 
     * @param nome Nome do link.
     * @param url Url para onde o link leva.
     * @return código html do link.
     */
    public String montarLink(String url, String nome, boolean mostra) {
        StringBuffer html = new StringBuffer();
        
        html.append("<a href=\"" + url + "\">" + nome + "</a>");
        
        if(!mostra) return "";
        
        return html.toString();
    }
}
